#include <DAC8563.h>

DAC8563::DAC8563(/* args */)
{

}

DAC8563::~DAC8563()
{

}

void DAC8563::begin(int32_t csPin, int32_t dinPin, int32_t sclkPin)
{
    _csPin   = csPin;
    _dinPin  = dinPin;
    _sclkPin = sclkPin;

    if (_csPin != -1)
    {
        pinMode(_csPin, OUTPUT);
        digitalWrite(_csPin, HIGH);
    }
    if (_dinPin != -1)
    {
        pinMode(_dinPin, OUTPUT);
        digitalWrite(_dinPin, LOW);
    }
    if (_sclkPin != -1)
    {
        pinMode(_sclkPin, OUTPUT);
        digitalWrite(_sclkPin, LOW);
    }

    /* Power up DAC-A and DAC-B */
    this->writeCommand((4ul << 19) | (0ul << 16) | (3 << 0));

    /* LDAC pin inactive for DAC-B and DAC-A  不使用LDAC引脚更新数据 */
    this->writeCommand((6ul << 19) | (0ul << 16) | (3 << 0));

    /* 复位2个DAC到中0值, 输出0V */
    this->setDACOutVoltage(1, 0);
    this->setDACOutVoltage(2, 0);

    /* 选择内部参考并复位2个DAC的增益=2 （复位时，内部参考是禁止的) */
    this->writeCommand((7ul << 19) | (0ul << 16) | (1 << 0));
    /* 修改内部的增益=1 Gain: DAC-B gain = 1, DAC-A gain = 1 */
    this->writeCommand((0ul << 19) | (2ul << 16) | (3 << 0));
}

void DAC8563::writeCommand(uint32_t command)
{
    digitalWrite(_csPin, LOW);

    for (uint8_t i = 0; i < 24; i++)
    {
        if (command & 0x800000)
        {
            digitalWrite(_dinPin, HIGH);
        }
        else
        {
            digitalWrite(_dinPin, LOW);
        }

        digitalWrite(_sclkPin, HIGH);
        command <<= 1;
        digitalWrite(_sclkPin, LOW);

    }

    digitalWrite(_csPin, HIGH);
}

void DAC8563::setDACOutVoltage(uint8_t channel, int16_t mv)
{
//    mv = constrain(mv, 0, 10000);
//    uint16_t dac = map(mv, 0, 10000, 0, 65535);
    uint16_t dac = mv;

   if (channel == 1)
   {
       this->writeCommand((3ul << 19) | (0ul << 16) | (dac << 0));
   }
   else if (channel == 2)
   {
       this->writeCommand((3ul << 19) | (1ul << 16) | (dac << 0));
   }
}
